package com.caishi.lkx.user.login;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.caishi.lkx.common.ienum.DeviceType;
import com.caishi.lkx.user.config.ThirdOauthConfig;
import com.caishi.lkx.user.dto.LoginDto;
import com.caishi.lkx.user.ienum.type.Sex;
import com.caishi.lkx.user.ienum.type.UserType;
import com.caishi.lkx.user.model.IUserModel;
import com.caishi.lkx.user.model.LoginInfoModel;
import com.caishi.lkx.user.model.MemberModel;
import com.caishi.lkx.user.service.ILoginInfoService;
import com.zzw.common.exception.BizException;
import com.zzw.common.exception.BizRuntimeException;

import com.caishi.lkx.user.UserResultCode;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author huangpeng
 * @Description //
 * @Date 2022/8/10 15:44
 **/
@Service("wxcxLoginService")
@Slf4j
public class WxcxLoginServiceImpl implements LoginService, IThirdOauthService {
    @Resource
    private ThirdOauthConfig thirdOauthConfig;
    @Resource
    private ILoginInfoService loginInfoService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public Map<String, Object> getAccessToken(String code, DeviceType type) {
        log.error("微信小程序登录:开始获取accesstoken:code={},deviceTp={}", code, type);
        if (StrUtil.isBlank(code)) {
            throw new BizRuntimeException(UserResultCode.thirdLoginCodeFail);
        }
        String appid = thirdOauthConfig.getWeCatXcxAppid();
        String secret = thirdOauthConfig.getWeCatXcxSecret();
        String accessTokenUrl = thirdOauthConfig.getWeCatXcxSessionTokenUrl();
        if (StrUtil.isBlank(appid)) {
            throw new BizRuntimeException(UserResultCode.accesstokenFail);
        }

        String url = String.format(accessTokenUrl, appid, secret, code);
        String resp = HttpUtil.get(url);
        return JSONObject.parseObject(resp);
    }

    @Override
    public Map<String, Object> getUserInfo(String sessionkey, String openId, DeviceType pc) {
        return null;
    }

    @Override
    public IUserModel<?> thirdGenerateUser(Map<String, Object> userInfo) {
        var userModel = new MemberModel();
        userModel.addUserType(UserType.member);
        userModel.setSex(Sex.unknown);
        return userModel;
    }

    @Override
    public LoginInfoModel loginBase(LoginDto loginDto, HttpServletRequest request, HttpServletResponse response) throws BizException {
        Map<String, Object> accessTokenMap = this.getAccessToken(loginDto.getCode(), loginDto.getDeviceType());
        String openid = accessTokenMap.get("openid").toString();
        String unionid = accessTokenMap.get("unionid").toString();
        if (StrUtil.isBlank(openid) || StrUtil.isBlank(unionid)) {
            throw new BizException(UserResultCode.getUserInfoFail);
        }
        LoginInfoModel loginInfoModel = loginInfoService.selectFirstLoginInfoByCredentials(unionid, loginDto.getType());
        var sessionKey = accessTokenMap.get("session_key").toString();
        redisTemplate.opsForValue().set("WXCX:UNIONID:" + loginDto.getDeviceId(), sessionKey,1, TimeUnit.DAYS);
        if (loginInfoModel == null) {
            return LoginInfoModel.builder()
                    .account(openid)
                    .certificate(unionid)
                    .loginType(loginDto.getType())
                    .user(thirdGenerateUser(accessTokenMap))
                    .build();
        }
        return checkLoginInfo(loginInfoModel, loginDto);
    }

    public String getSessionKey(String deviceId) {
        return redisTemplate.opsForValue().get("WXCX:UNIONID:" + deviceId);
    }
}
